package service

import (
	"XiangMu/define"
	"XiangMu/models"
	"XiangMu/utils"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/copier"
	uuid "github.com/satori/go.uuid"
	"gorm.io/gorm"
	"log"
	"net/http"
	"os"
	"strconv"
	"strings"
	"sync"
	"time"
)

// 退出登录
func Logout(c *gin.Context) {
	auth := c.GetHeader("Authorization")
	claims, err := utils.AnalyseToken(auth)
	if err == nil && claims != nil {
		// 计算token剩余有效期
		expiresIn := time.Until(time.Unix(claims.ExpiresAt, 0))
		err = models.RDB.Set(c, auth, 1, expiresIn).Err()
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"code": -1,
				"msg":  "退出失败",
			})
		}
	}
	c.JSON(http.StatusInternalServerError, gin.H{
		"code": -1,
		"msg":  "退出成功",
	})
}

// Login 处理用户登录
func UserLogin(c *gin.Context) {
	account := c.PostForm("account")
	password := c.PostForm("password")
	if account == "" || password == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": -1,
			"msg":  "用户名和密码不能为空",
		})
		return
	}
	var user models.User
	if err := models.DB.Where("account = ? AND password = ?", account, password).First(&user).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusUnauthorized, gin.H{
				"code": -1,
				"msg":  "用户名密码错误",
			})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": -1,
			"msg":  "内部错误: " + err.Error(),
		})
		return
	}

	token, err := utils.GenerateToken(user.Id, user.Name, 0)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": -1,
			"msg":  "生成 token 失败: " + err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"name": user.Name,
		"code": 200,
		"msg":  token,
	})
}

type updateUserSelf struct {
	Id            int    `json:"id"`
	Account       string `json:"account"`
	Step          int    `json:"step"`
	Name          string `gorm:"column:name" json:"name"`
	Password      string `gorm:"column:password" json:"password"`
	XueHao        string `gorm:"column:xue_hao" json:"xue_hao"`
	Position      string `gorm:"column:position" json:"position"`
	Sex           string `gorm:"sex" json:"sex"`
	Nation        string `gorm:"column:nation" json:"nation"`
	Birthday      string `gorm:"column:birthday" json:"birthday"`
	Origin        string `gorm:"column:origin" json:"origin"`
	Occupation    string `gorm:"column:occupation" json:"occupation"`
	IdentityId    string `gorm:"column:identity_id" json:"identity_id"`
	Education     string `gorm:"column:education" json:"education"`
	Address       string `gorm:"column:address" json:"address"`
	Phone         string `gorm:"column:phone;type:varchar(11)" json:"phone"`
	Resume        string `gorm:"column:resume" json:"resume"`
	PoliticalTime string `gorm:"column:political_status" json:"political_time"`
	Avatar        string `gorm:"column:avatar" json:"avatar"`
	Organization  string `gorm:"column:organization" json:"organization"`
	Status        string `gorm:"column:status" json:"status"`
	Domicile      string `gorm:"column:domicile" json:"domicile"`
}

// Update更新用户信息
func Update(c *gin.Context) {
	id, _ := c.Get("id")
	var req updateUserSelf
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求体"})
		return
	}
	tx := models.DB.Begin()
	if tx.Error != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "事务启动失败"})
		return
	}
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
			c.JSON(http.StatusInternalServerError, gin.H{"error": "事务回滚"})
		}
	}()

	bl := utils.CheckPoliticalTime(req.PoliticalTime)
	if !bl {
		c.JSON(http.StatusBadRequest, gin.H{"error": "入团时间请按照2006年1月格式填写"})
		return
	}
	user := models.User{
		Name:          req.Name,
		Password:      req.Password,
		XueHao:        req.XueHao,
		Position:      models.InvertedPositionMap[req.Position],
		Sex:           models.InvertedGenderMap[req.Sex],
		Nation:        req.Nation,
		Birthday:      req.Birthday,
		Origin:        req.Origin,
		Occupation:    req.Occupation,
		IdentityId:    req.IdentityId,
		Education:     req.Education,
		Address:       req.Address,
		Phone:         req.Phone,
		Resume:        req.Resume,
		PoliticalTime: req.PoliticalTime,
		Domicile:      req.Domicile,
	}
	userMap := map[string]interface{}{}
	//零值的处理
	{
		if user.Name != "" {
			userMap["Name"] = user.Name
		}
		userMap["Sex"] = user.Sex
		if user.Nation != "" {
			userMap["Nation"] = user.Nation
		}
		if user.Birthday != "" { // 检查时间是否为零值
			userMap["Birthday"] = user.Birthday
		}
		if user.Origin != "" {
			userMap["Origin"] = user.Origin
		}
		if user.Occupation != "" {
			userMap["Occupation"] = user.Occupation
		}
		if user.IdentityId != "" {
			userMap["IdentityId"] = user.IdentityId
		}
		if user.Education != "" {
			userMap["Education"] = user.Education
		}
		if user.Address != "" {
			userMap["Address"] = user.Address
		}
		if user.Phone != "" {
			userMap["Phone"] = user.Phone
		}
		if user.Resume != "" {
			userMap["Resume"] = user.Resume
		}
		if user.PoliticalTime != "" { // 检查时间是否为零值
			userMap["PoliticalTime"] = user.PoliticalTime
		}
		if user.Domicile != "" {
			userMap["Domicile"] = user.Domicile
		}

	}
	if err := tx.Model(&models.User{}).Where("id = ?", id).Updates(userMap).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	if err := tx.Commit().Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "事务提交失败"})
		return
	}

	// 更新缓存
	cacheKey := fmt.Sprintf("user:%d", id)
	models.RDB.Del(c, cacheKey)
	var rawUser models.User
	err := models.DB.Model(models.User{}).Where("id = ?", id).First(&rawUser).Error
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": 500,
			"msg":  "数据库错误",
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  models.UserToUserResponse(rawUser),
	})
}

// UserWordFill 处理用户信息填充
func UserWordFill(c *gin.Context) {
	var req struct {
		IDs []uint `json:"ids"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的请求体"})
		return
	}
	id, _ := c.Get("id")
	//n, _ := strconv.Atoi(c.Param("num"))
	var user models.User
	if err := models.DB.Where("id = ?", id).First(&user).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": 500,
			"msg":  err.Error(),
		})
		return
	}
	var url string
	var url1 string
	var url2 string
	var pdf string
	var pdf1 string
	var pdf2 string
	uResp := models.UserToUserResponse(user)
	for i := 0; i < len(req.IDs); i++ {
		n := req.IDs[i]
		if n == 0 {
			pdf, url = utils.WordFill(uResp)
			defer utils.DelFile(pdf)
		}
		if n == 1 {
			pdf1, url1 = utils.WordFill1(uResp)
			defer utils.DelFile(pdf1)
		}
		if n == 2 {
			pdf2, url2 = utils.WordFill2(uResp)
			defer utils.DelFile(pdf2)
		}
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"url":  url,
		"url1": url1,
		"url2": url2,
	})
}

type userResponse struct {
	Id            int    `gorm:"primaryKey;autoIncrement" json:"id"`
	Name          string `gorm:"column:name" json:"name"`
	Account       string `gorm:"column:account" json:"account"`
	Password      string `gorm:"column:password" json:"password"`
	XueHao        string `gorm:"column:xue_hao" json:"xue_hao"`
	Position      string `gorm:"column:position" json:"position"`
	Sex           string `gorm:"sex" json:"sex"`
	Status        string `gorm:"status" json:"status"`
	Step          uint   `gorm:"step" json:"step"`
	Nation        string `gorm:"column:nation" json:"nation"`
	Birthday      string `gorm:"column:birthday" json:"birthday"`
	Origin        string `gorm:"column:origin" json:"origin"`
	Occupation    string `gorm:"column:occupation" json:"occupation"`
	IdentityId    string `gorm:"column:identity_id" json:"identity_id"`
	Education     string `gorm:"column:education" json:"education"`
	Address       string `gorm:"column:address" json:"address"`
	Phone         string `gorm:"column:phone;type:varchar(11)" json:"phone"`
	Resume        string `gorm:"column:resume" json:"resume"`
	Organization  string `gorm:"column:organization" json:"organization"`
	Avatar        string `gorm:"column:avatar" json:"avatar"`
	PoliticalTime string `gorm:"column:political_time" json:"political_time"`
	Domicile      string `gorm:"column:domicile" json:"domicile"`
}

// 根据ID查询用户信息
func SelectById(c *gin.Context) {
	type userInfoReponse struct {
		Info  userResponse
		Image string
	}
	id, _ := c.Get("id")
	cacheKey := fmt.Sprintf("user:%d", id)
	// 先从缓存中获取数据
	var user models.User
	cachedData, err := models.RDB.Get(c, cacheKey).Result()
	if err == nil {
		// 如果缓存中有数据，直接返回
		if err = json.Unmarshal([]byte(cachedData), &user); err == nil {
			userp := models.UserToUserResponse(user)
			var userResp userResponse
			err = copier.Copy(&userResp, userp)
			if err != nil {
				c.JSON(http.StatusInternalServerError, gin.H{
					"code": 500,
					"msg":  err.Error(),
				})
				return
			}
			c.JSON(http.StatusOK, gin.H{
				"code": 200,
				"msg": userInfoReponse{
					Info:  userResp,
					Image: user.Avatar,
				},
			})
			return
		}
	}

	// 缓存中没有数据，从数据库中查询
	if err = models.DB.Model(models.User{}).Where("id = ?", id).First(&user).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": 500,
			"msg":  err.Error(),
		})
		return
	}
	// 将查询结果存入缓存
	userJSON, _ := json.Marshal(user)
	if err = models.RDB.Set(c, cacheKey, userJSON, 24*time.Hour).Err(); err != nil {
		log.Printf("缓存写入失败: %v", err)
	}
	userp := models.UserToUserResponse(user)
	var userResp userResponse
	//拷贝结构体
	err = copier.Copy(&userResp, userp)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": 500,
			"msg":  err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg": userInfoReponse{
			Info:  userResp,
			Image: user.Avatar,
		},
	})
}

// Upload 处理用户头像上传
func Upload(c *gin.Context) {
	file, err := c.FormFile("avatar")
	if err != nil || file == nil {
		log.Printf("文件获取失败: %v", err)
		c.JSON(http.StatusBadRequest, gin.H{"error": "文件获取失败"})
		return
	}
	id, _ := c.Get("id")
	s := strings.Split(file.Filename, ".")
	newName := uuid.NewV4().String()[:8] + "." + s[len(s)-1]
	filePath := "./tmp/" + newName
	if err := c.SaveUploadedFile(file, filePath); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "文件保存失败"})
		return
	}
	defer func() {
		if err := os.Remove(filePath); err != nil {
			log.Printf("删除临时文件失败: %v", err)
		}
	}()
	// 上传到 OSS
	avatarURL := "https://web-aliyuncjh.oss-cn-guangzhou.aliyuncs.com/images/" + newName
	// 启动go协程
	var wg sync.WaitGroup
	// 启动go协程前增加计数器
	wg.Add(1)
	go func() {
		defer wg.Done()
		utils.ALiYunOssPutImage(filePath)
		if err := models.DB.Model(&models.User{}).Where("id = ?", id).Update("avatar", avatarURL).Error; err != nil {
			log.Printf("Failed to update avatar URL: %v", err)
		}
	}()
	wg.Wait()
	// 更新缓存
	cacheKey := fmt.Sprintf("user:%d", id)
	models.RDB.Del(c, cacheKey)
	c.JSON(http.StatusOK, gin.H{
		"message": "头像上传成功",
		"url":     avatarURL,
	})
	return
}

type StepRequest struct {
	Data map[string]string `json:"data"` // 步骤的具体信息
}

// 保存步骤信息
func SaveStepInfo(c *gin.Context) {
	userId, _ := strconv.Atoi(c.Param("uid"))
	stepId, _ := strconv.Atoi(c.Param("sid"))
	if stepId < 0 || stepId > 24 {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": 400,
			"msg":  "步骤不符合条件",
		})
		return
	}

	//获取前端信息
	var req StepRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"code": 400, "error": "无效的请求体"})
		return
	}
	// 将 Data 转换为 JSON 字符串
	dataJSON, err := json.Marshal(req.Data)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"code": 500, "error": "数据序列化失败"})
		return
	}
	//检查数据是否合理
	err = CheckStepInfo(req.Data, stepId, userId)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"code": 400, "error": err.Error()})
		return
	}
	err = utils.AllTimeCheck(req.Data, stepId, userId)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"code": 400, "error": err.Error()})
		return
	}
	if err = models.DB.Model(&models.Steps{}).Where("user_id = ? AND step_id = ?", userId, stepId).Update("data", dataJSON).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code": -1,
			"msg":  err.Error(),
		})
		return
	}

	//wsk.NotifyReviewers(step.UserId, step.StepId)
	// 更新缓存
	cacheKey := fmt.Sprintf("user:%dstep:%d", userId, stepId)
	models.RDB.Del(c, cacheKey)
	c.JSON(http.StatusOK, gin.H{"message": "数据提交成功"})

}

// TODO:第六步 - 培养教育考察,第七步 - 确认发展对象的公示起止时间，第十一步 - 开展集中培训，第十二步 - 支部委员会审查，第十七步 - 上级党委审批的起止时间，第十八步 - 再上一级党委组织部门备案与
// 检查步骤信息是否合理
func CheckStepInfo(data map[string]string, stepId int, userId int) error {
	//申请入党时间
	if stepId == 1 {
		var t time.Time
		err := models.DB.Model(models.User{}).Select("birthday").Where("id =?", userId).First(&t).Error
		if err != nil {
			return errors.New("年满18周岁的公民才可以申请入党")
		}
		layout := "2006年1月2日"
		targetTime, err := time.Parse(layout, data["入党申请时间"])
		if err != nil {
			return errors.New("年满18周岁的公民才可以申请入党")
		}
		// 计算年数差
		print(targetTime.Format("2006-01-02"))
		println(t.Format("2006-01-02"))
		years := targetTime.Year() - t.Year()

		// 比较月份和日期
		if targetTime.Month() < t.Month() ||
			(targetTime.Month() == t.Month() && targetTime.Day() < t.Day()) {
			years--
		}
		if years <= 18 {
			return errors.New("年满18周岁的公民才可以申请入党")
		}
		return nil
	}
	if stepId == 2 {
		//待比骄的时间
		layout := "2006年1月2日"
		t2, err := time.Parse(layout, data["支部谈话时间"])
		if err != nil {
			return errors.New("收到入党申请书后一个月内进行谈话")
		}
		//参照的时间
		stepinfo, err := StepInfo(strconv.Itoa(1), userId)
		if err != nil {
			return errors.New("收到入党申请书后一个月内进行谈话")
		}
		t1, err := time.Parse(layout, stepinfo["入党申请时间"])
		if err != nil {
			return errors.New("收到入党申请书后一个月内进行谈话")
		}
		//比较
		// 计算t1加一个月后的时间
		oneMonthLater := t1.AddDate(0, 1, 0)

		// 如果t2在t1和oneMonthLater之间，则相差小于一个月
		if t2.After(oneMonthLater) {
			return errors.New("收到入党申请书后一个月内进行谈话")
		}
		return nil
	}
	if stepId == 3 {
		//待比骄的时间
		layout := "2006年1月2日"
		t2, err := time.Parse(layout, data["支部确定入党积极分子时间"])
		if err != nil {
			return errors.New("该时间应在支部谈话时间之后")
		}
		//参照的时间
		stepinfo, err := StepInfo(strconv.Itoa(2), userId)
		if err != nil {
			return errors.New("该时间应在支部谈话时间之后")
		}
		t1, err := time.Parse(layout, stepinfo["支部谈话时间"])
		if err != nil {
			return errors.New("该时间应在支部谈话时间之后")
		}
		//比较
		// 如果t2在t1和later之间，则相差小于1年
		if t2.Before(t1) {
			return errors.New("该时间应在支部谈话时间之后")
		}
		return nil
	}
	if stepId == 4 {
		//待比骄的时间
		layout := "2006年1月2日"
		t2, err := time.Parse(layout, data["党委备案时间"])
		if err != nil {
			return errors.New("该时间应在支部确定入党积极分子时间之后")
		}
		//参照的时间
		stepinfo, err := StepInfo(strconv.Itoa(3), userId)
		if err != nil {
			return errors.New("该时间应在支部确定入党积极分子时间之后")
		}
		t1, err := time.Parse(layout, stepinfo["支部确定入党积极分子时间"])
		if err != nil {
			return errors.New("该时间应在支部确定入党积极分子时间之后")
		}
		//比较
		// 如果t2在t1和later之间，则相差小于1年
		if t2.Before(t1) {
			return errors.New("该时间应在支部确定入党积极分子时间之后")
		}
		return nil
	}
	if stepId == 6 {
		//待比骄的时间
		layout := "2006年1月2日"
		t2, err := time.Parse(layout, data["书面思想汇报时间1"])
		if err != nil {
			return errors.New("该时间应在党委备案时间之后")
		}
		//参照的时间
		stepinfo, err := StepInfo(strconv.Itoa(4), userId)
		if err != nil {
			return errors.New("该时间应在党委备案时间之后")
		}
		t1, err := time.Parse(layout, stepinfo["党委备案时间"])
		if err != nil {
			return errors.New("该时间应在党委备案时间之后")
		}
		//比较
		// 如果t2在t1和later之间，则相差小于1年
		if t2.Before(t1) {
			return errors.New("该时间应在党委备案时间之后")
		}
		return nil
	}
	if stepId == 7 {

		//待比骄的时间
		layout := "2006年1月2日"
		t2, err := time.Parse(layout, data["支部确定发展对象人选时间"])
		if err != nil {
			return errors.New("列为积极分子到发展对象需要满一年及以上")
		}
		//参照的时间
		stepinfo, err := StepInfo(strconv.Itoa(3), userId)
		if err != nil {
			return errors.New("列为积极分子到发展对象需要满一年及以上")
		}
		t1, err := time.Parse(layout, stepinfo["支部确定入党积极分子时间"])
		if err != nil {
			return errors.New("列为积极分子到发展对象需要满一年及以上")
		}
		//比较
		// 计算t1加一年后的时间
		later := t1.AddDate(1, 0, 0)
		// 如果t2在t1和later之间，则相差小于1年
		if t2.Before(later) {
			return errors.New("列为积极分子到发展对象需要满一年及以上")
		}
		return nil
	}
	if stepId == 8 {
		//待比骄的时间
		layout := "2006年1月2日"
		t2, err := time.Parse(layout, data["党委备案同意时间"])
		if err != nil {
			return errors.New("该时间应在支部确定发展对象人选时间之后")
		}
		//参照的时间
		stepinfo, err := StepInfo(strconv.Itoa(7), userId)
		if err != nil {
			return errors.New("该时间应在支部确定发展对象人选时间之后")
		}
		t1, err := time.Parse(layout, stepinfo["支部确定发展对象人选时间"])
		if err != nil {
			return errors.New("该时间应在支部确定发展对象人选时间之后")
		}
		//比较
		// 如果t2在t1和later之间，则相差小于1年
		if t2.Before(t1) {
			return errors.New("该时间应在支部确定发展对象人选时间之后")
		}
		return nil
	}
	if stepId == 13 {
		//待比骄的时间
		layout := "2006年1月2日"
		t2, err := time.Parse(layout, data["党委预审时间"])
		if err != nil {
			return errors.New("该时间应在支部审查时间之后")
		}
		//参照的时间
		stepinfo, err := StepInfo(strconv.Itoa(12), userId)
		if err != nil {
			return errors.New("该时间应在支部审查时间之后")
		}
		t1, err := time.Parse(layout, stepinfo["支部审查时间"])
		if err != nil {
			return errors.New("该时间应在支部审查时间之后")
		}
		//比较
		// 如果t2在t1和later之间，则相差小于1年
		if t2.Before(t1) {
			return errors.New("该时间应在支部审查时间之后")
		}
		return nil
	}
	if stepId == 15 {
		//待比骄的时间
		layout := "2006年1月2日"
		t2, err := time.Parse(layout, data["支部大会会议时间"])
		if err != nil {
			return errors.New("该时间应在党委预审时间之后")
		}
		//参照的时间
		stepinfo, err := StepInfo(strconv.Itoa(13), userId)
		if err != nil {
			return errors.New("该时间应在党委预审时间之后")
		}
		t1, err := time.Parse(layout, stepinfo["党委预审时间"])
		if err != nil {
			return errors.New("该时间应在党委预审时间之后")
		}
		//比较
		// 如果t2在t1和later之间，则相差小于1年
		if t2.Before(t1) {
			return errors.New("该时间应在党委预审时间之后")
		}
		return nil
	}
	if stepId == 16 {
		//待比骄的时间
		layout := "2006年1月2日"
		t2, err := time.Parse(layout, data["党委派人谈话时间"])
		if err != nil {
			return errors.New("党委派人谈话时间应在支部大会会议时间之后")
		}
		//参照的时间
		stepinfo, err := StepInfo(strconv.Itoa(15), userId)
		if err != nil {
			return errors.New("党委派人谈话时间应在支部大会会议时间之后")
		}
		t1, err := time.Parse(layout, stepinfo["支部大会会议时间"])
		if err != nil {
			return errors.New("党委派人谈话时间应在支部大会会议时间之后")
		}
		//比较
		if t2.Before(t1) {
			return errors.New("党委派人谈话时间应在支部大会会议时间之后")
		}
		return nil
	}
	if stepId == 17 {
		//待比骄的时间
		layout := "2006年1月2日"
		t2, err := time.Parse(layout, data["党委审批时间"])
		if err != nil {
			return errors.New("党委审批时间应在党委派人谈话时间之后")
		}
		//参照的时间
		stepinfo, err := StepInfo(strconv.Itoa(16), userId)
		if err != nil {
			return errors.New("党委审批时间应在党委派人谈话时间之后")
		}
		t1, err := time.Parse(layout, stepinfo["党委派人谈话时间"])
		if err != nil {
			return errors.New("党委审批时间应在党委派人谈话时间之后")
		}
		//比较
		if t2.Before(t1) {
			return errors.New("党委审批时间应在党委派人谈话时间之后")
		}
		return nil
	}
	if stepId == 18 {
		//待比骄的时间
		layout := "2006年1月2日"
		t2, err := time.Parse(layout, data["向上级党委组织部门备案时间"])
		if err != nil {
			return errors.New("该时间应在党委审批时间之后")
		}
		//参照的时间
		stepinfo, err := StepInfo(strconv.Itoa(17), userId)
		if err != nil {
			return errors.New("该时间应在党委审批时间之后")
		}
		t1, err := time.Parse(layout, stepinfo["党委审批时间"])
		if err != nil {
			return errors.New("该时间应在党委审批时间之后")
		}
		//比较
		// 如果t2在t1和later之间，则相差小于1年
		if t2.Before(t1) {
			return errors.New("该时间应在党委审批时间之后")
		}
		return nil
	}
	if stepId == 20 {
		//待比骄的时间
		layout := "2006年1月2日"
		t2, err := time.Parse(layout, data["入党宣誓时间"])
		if err != nil {
			return errors.New("学院党委审批后组织")
		}
		//参照的时间
		stepinfo, err := StepInfo(strconv.Itoa(17), userId)
		if err != nil {
			return errors.New("学院党委审批后组织")
		}
		t1, err := time.Parse(layout, stepinfo["党委审批时间"])
		if err != nil {
			return errors.New("学院党委审批后组织")
		}
		//比较
		if t2.Before(t1) {
			return errors.New("学院党委审批后组织")
		}
		return nil
	}
	if stepId == 22 {
		//待比骄的时间
		layout := "2006年1月2日"
		t2, err := time.Parse(layout, data["入党宣誓时间"])
		if err != nil {
			return errors.New("学院党委审批后组织")
		}
		//参照的时间
		stepinfo, err := StepInfo(strconv.Itoa(17), userId)
		if err != nil {
			return errors.New("学院党委审批后组织")
		}
		t1, err := time.Parse(layout, stepinfo["党委审批时间"])
		if err != nil {
			return errors.New("学院党委审批后组织")
		}
		//比较
		if t2.Before(t1) {
			return errors.New("学院党委审批后组织")
		}
		return nil
	} //todo
	if stepId == 23 {
		//待比骄的时间
		layout := "2006年1月2日"
		t2, err := time.Parse(layout, data["支部大会会议时间"])
		if err != nil {
			return errors.New("会议时间应在申请转正时间之后")
		}
		//参照的时间
		stepinfo, err := StepInfo(strconv.Itoa(22), userId)
		if err != nil {
			return errors.New("会议时间应在申请转正时间之后")
		}
		t1, err := time.Parse(layout, stepinfo["申请转正时间"])
		if err != nil {
			return errors.New("会议时间应在申请转正时间之后")
		}
		//比较
		if t2.Before(t1) {
			return errors.New("会议时间应在申请转正时间之后")
		}
		return nil
	}
	if stepId == 24 {
		//待比骄的时间
		layout := "2006年1月2日"
		t2, err := time.Parse(layout, data["党委审批时间"])
		if err != nil {
			return errors.New("党委审批时间应在会议时间之后")
		}
		//参照的时间
		stepinfo, err := StepInfo(strconv.Itoa(23), userId)
		if err != nil {
			return errors.New("党委审批时间应在会议时间之后")
		}
		t1, err := time.Parse(layout, stepinfo["支部大会会议时间"])
		if err != nil {
			return errors.New("党委审批时间应在会议时间之后")
		}
		//比较
		if t2.Before(t1) {
			return errors.New("党委审批时间应在会议时间之后")
		}
		return nil
	}
	return nil
}

// 查询步骤信息
func StepInfo(stepId string, userID any) (map[string]string, error) {
	var data map[string]string
	//先查redis
	//userId, _ := utils.ToInt(value)
	userId := fmt.Sprintf("%v", userID)
	cacheKey := "user:" + userId + "step:" + stepId
	result, err := models.RDB.Get(context.Background(), cacheKey).Result()
	if err == nil {
		// 如果缓存中有数据，直接返回
		if err = json.Unmarshal([]byte(result), &data); err == nil {
			return data, nil
		} else {
			return nil, err
		}
	}
	//没有就查询数据库
	var step models.Step
	err = models.DB.Model(&models.Step{}).Where("user_id = ? AND step_id = ?", userId, stepId).First(&step).Error
	if step.Data == "" {
		return define.Default[stepId], nil
	}
	if err != nil {
		return nil, err
	}
	if err = models.RDB.Set(context.Background(), cacheKey, step.Data, 24*time.Hour).Err(); err != nil {
		log.Printf("缓存写入失败: %v", err)
		return nil, err
	}
	err = json.Unmarshal([]byte(step.Data), &data)
	if err != nil {
		return nil, err
	}
	return data, nil

}
func GetStepInfo(c *gin.Context) {
	stepId := c.Param("id")
	//先查redis
	userId, _ := c.Get("id")
	//userId, _ := utils.ToInt(value)
	data, err := StepInfo(stepId, userId)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"code":  -1,
			"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  HandleData(data, stepId),
	})
}

// 处理返回数据
func HandleData(data map[string]string, stepId string) map[string]LabelContent {
	result := map[string]LabelContent{}
	for k, v := range data {
		result[define.Key[stepId+k]] = LabelContent{
			Label:   k,
			Content: fmt.Sprintf("%v", v),
		}
	}
	return result
}

type LabelContent struct {
	Content any    `gorm:"column:content" json:"content"`
	Label   string `gorm:"column:label" json:"label"`
}
